import React, { ReactElement, useState, useEffect } from 'react'
import { match, Switch, Route, Redirect } from 'react-router-dom'
import { History, Location } from 'history'
import { Skeleton, message, BackTop } from 'antd'
import { ToTopOutlined } from '@ant-design/icons'
import { connect } from 'react-redux'
import { USERINFO } from '@src/redux/actions/basic'
import { BASIC_STATE } from '@src/redux/reducers/basic'
import style from './Index.module.less'
import BerifInfo from './components/BerifInfo/Index'
import Operate from './components/Operate/Index'
import Info from './pages/Info/Index'
import Defince from './pages/Defince/Index'
import Court from './pages/Court/Index'
import { getCaseDetailRequest, getOperateRequest, OperateItem, addOperateUsedRequest, getCourtRequest } from './ajax'
import { awaitWrap } from '@js/tool'
import { CaseSchema } from '@src/components/Schema/CaseSchema'
import { Context } from './context'
import { TribunalPartySchema } from '@src/components/Schema/TribunalPartySchema'

interface Params {
  caseid: string
}

interface Props {
  history: History
  match: match<Params>
  userInfo: USERINFO
  location: Location
}

// 初始化案件数据
async function initData (caseid: string, h: History, userInfo: USERINFO, setCaseDetail: (v: CaseSchema) => void, setUsed: (v: OperateItem[]) => void, setUnuse: (v: OperateItem[]) => void, setCourtItems: (v: TribunalPartySchema[]) => void): Promise<void> {
  const hide = message.loading('加载中', 120)
  const o = await getOperate(caseid, setUsed, setUnuse)
  const [e, d] = await awaitWrap(getCaseDetailRequest(caseid))
  hide()
  if (e !== null) {
    return undefined
  } else if (d === null) {
    return await message.error('数据未返回')
  }
  setCaseDetail(d)
  const used = o.used.map(li => li.key)
  if (used.includes('party_zuting')) {
    await initCourt(caseid, d, userInfo, setCourtItems)
  }
}

// 获取操作列表
async function getOperate (caseid: string, setUsed: (v: OperateItem[]) => void, setUnuse: (v: OperateItem[]) => void): Promise<{ used: OperateItem[], unuse: OperateItem[] }> {
  const [e, d] = await awaitWrap(getOperateRequest(caseid))
  if (e === null && d !== null) {
    setUsed(d.used)
    setUnuse(d.unuse)
    return d
  }
  return {
    used: [],
    unuse: []
  }
}

// 更新操作
async function addOperate (caseid: string, operate: string): Promise<void> {
  await awaitWrap(addOperateUsedRequest(caseid, operate))
}

// 初始化组庭信息
async function initCourt (caseid: string, caseDetail: CaseSchema, userInfo: USERINFO, setCourtItems: (v: TribunalPartySchema[]) => void): Promise<void> {
  const [e, d] = await awaitWrap(getCourtRequest(caseid, caseDetail, userInfo.id))
  if (e !== null || d === null) {
    return undefined
  }
  setCourtItems(d)
}

function Main ({ history, match, userInfo, location }: Props): ReactElement {
  const [caseDetail, setCaseDetail] = useState<CaseSchema | null>(null)
  const [used, setUsed] = useState<OperateItem[]>([])
  const [unuse, setUnuse] = useState<OperateItem[]>([])
  const [courtItems, setCourtItems] = useState<TribunalPartySchema[]>([])
  const refreshCase = function (): void {
    initData(match.params.caseid, history, userInfo, setCaseDetail, setUsed, setUnuse, setCourtItems).catch(e => console.error(e))
  }
  useEffect(() => {
    if (match !== null) {
      refreshCase()
    }
  }, [])
  if (caseDetail === null) {
    return (
      <div className={style.loading}><Skeleton active /></div>
    )
  }
  const initValues = {
    courtItems,
    setCourtItems,
    usedOperates: used
  }
  return (
    <Context.Provider value={initValues}>
      <div className={style.container}>
        <BerifInfo data={caseDetail} />
        <div className={style.body}>
          <Switch location={location}>
            <Route exact path='/admin/case-detail/:caseid' render={() => <Info caseDetail={caseDetail} used={used} />} />
            <Route exact path='/admin/case-detail/:caseid/defince' render={() => <Defince caseDetail={caseDetail} refreshCase={refreshCase} refreshOpereate={async k => await addOperate(caseDetail.id, k)} />} />
            <Route exact path='/admin/case-detail/:caseid/court/:id' render={() => <Court caseDetail={caseDetail} refreshCase={refreshCase} />} />
            <Route path='/admin/case-detail/:caseid/*' render={({ match }) => <Redirect to={`/admin/case-detail/${match.params.caseid}`} />} />
          </Switch>
        </div>
        <Switch location={location}>
          <Route exact path='/admin/case-detail/:caseid' render={({ history, match }) => <Operate data={caseDetail} unuse={unuse} used={used} refreshOpereate={async k => { await addOperate(caseDetail.id, k); await initData(match.params.caseid, history, userInfo, setCaseDetail, setUsed, setUnuse, setCourtItems) }} />} />
        </Switch>
        <BackTop>
          <span className={style.backtop}><ToTopOutlined /></span>
        </BackTop>
      </div>
    </Context.Provider>
  )
}

export default connect((state: { basic: BASIC_STATE }) => {
  return {
    userInfo: state.basic.userInfo
  }
}, dispatch => {
  return {

  }
})(Main)
